Skip to content

fix: allow header propagation for router-plugins#2877

Open
Noroth wants to merge 5 commits into
mainfrom
ludwig/eng-9615-router-plugin-metadata-overwritten-in-grpc-plugin-middleware
Open

fix: allow header propagation for router-plugins#2877
Noroth wants to merge 5 commits into
mainfrom
ludwig/eng-9615-router-plugin-metadata-overwritten-in-grpc-plugin-middleware

Conversation

@Noroth
Copy link
Copy Markdown
Contributor

@Noroth Noroth commented May 20, 2026

This PR fixes an issue that header propagation was not working for router-plugins if telemetry was enabled. Instead the metadata was overwritten by the plugin-client invoke logic.

Summary by CodeRabbit

  • New Features

    • Plugins can use configurable gRPC dial options.
    • HTTP→gRPC header forwarding to plugin subgraphs with filtering of unsafe/reserved headers while preserving auth, tracing, tenant and other safe headers; supports multi-value headers and case-normalization.
  • Tests

    • New integration and helper tests validating header propagation, filtering, multi-value handling, case-normalization, and tracing/span recording for both local and OCI-based plugin setups.

Review Change Stack

Checklist

  • I have discussed my proposed changes in an issue and have received approval to proceed.
  • I have followed the coding standards of the project.
  • Tests or benchmarks have been added or updated.
  • Documentation has been updated on https://github.com/wundergraph/docs-website.
  • I have read the Contributors Guide.

Open Source AI Manifesto

This project follows the principles of the Open Source AI Manifesto. Please ensure your contribution aligns with its principles.

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4d29b7ab-eadf-4aa4-a2d8-325fca1ff746

📥 Commits

Reviewing files that changed from the base of the PR and between 96e0292 and c13a7ff.

📒 Files selected for processing (2)
  • router/core/graph_server.go
  • router/core/router.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • router/core/graph_server.go
  • router/core/router.go

Walkthrough

Adds router support for configurable gRPC DialOptions, preserves existing outgoing gRPC metadata during plugin invocations, and introduces test helpers plus integration tests validating HTTP header propagation into outgoing gRPC subgraph metadata for both binary and OCI plugins.

Changes

gRPC Plugin Dial Options and Header Forwarding

Layer / File(s) Summary
Router configuration and option setup
router/core/router_config.go, router/core/router.go
Adds grpcPluginDialOptions field to router Config and introduces WithGRPCPluginDialOptions option function to allow configuration of gRPC dial behavior for plugins.
Plugin configuration wiring and initialization
router/core/graph_server.go, router/pkg/grpcconnector/grpcplugin/grpc_plugin.go, router/pkg/grpcconnector/grpcpluginoci/grpc_oci_plugin.go
Passes configured dial options from router config through both OCI-based and binary plugin constructors, extends GRPCPluginConfig structs to accept and store DialOptions, and forwards them into the spawned gRPC client setup.
Metadata context preservation
router/pkg/grpcconnector/grpccommon/grpc_plugin_client.go
Updates metadata initialization in GRPCPluginClient.Invoke to preserve and reuse existing outgoing gRPC metadata from the request context before injecting new metadata entries.
gRPC plugin header test matrix and interceptor
router-tests/testenv/grpc_plugin_header_cases.go
Adds CaptureSubgraphMetadataInterceptor, GRPCPluginHeaderCase scenarios (regex/named propagation), and RunGRPCPluginHeaderCases runner exercising multiple header-propagation assertions.
Binary plugin header forwarding tests
router-tests/protocol/router_plugin_test.go
Introduces TestRouterPluginWithHeaderForwarding with subtests: plugin-runner header cases and a tracing+propagation regression that captures subgraph metadata and asserts recorded spans.
OCI plugin header forwarding tests
router-tests/router_oci_plugin_test.go
Adds TestOCIPluginWithHeaderForwarding which builds/pushes plugin OCI images and runs the header-case runner against an OCI-configured router.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: allow header propagation for router-plugins' directly and accurately describes the main change: enabling header propagation for router-plugins, which aligns with the core issue fixed in this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

Router-nonroot image scan passed

✅ No security vulnerabilities found in image:

ghcr.io/wundergraph/cosmo/router:sha-04a52885745ed0dc9a351b1b2e211434e2ac5518-nonroot

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 81.81818% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.28%. Comparing base (42b307b) to head (eee01ad).

Files with missing lines Patch % Lines
router/core/graph_server.go 50.00% 1 Missing ⚠️
...pkg/grpcconnector/grpcpluginoci/grpc_oci_plugin.go 50.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2877       +/-   ##
===========================================
+ Coverage   40.86%   66.28%   +25.41%     
===========================================
  Files        1037      258      -779     
  Lines      131332    27084   -104248     
  Branches     6176        0     -6176     
===========================================
- Hits        53672    17952    -35720     
+ Misses      75914     7721    -68193     
+ Partials     1746     1411      -335     
Files with missing lines Coverage Δ
router/core/router.go 70.51% <100.00%> (+0.06%) ⬆️
router/core/router_config.go 93.78% <ø> (ø)
...pkg/grpcconnector/grpccommon/grpc_plugin_client.go 79.31% <100.00%> (+0.48%) ⬆️
router/pkg/grpcconnector/grpcplugin/grpc_plugin.go 75.43% <100.00%> (+0.43%) ⬆️
router/core/graph_server.go 85.40% <50.00%> (-0.06%) ⬇️
...pkg/grpcconnector/grpcpluginoci/grpc_oci_plugin.go 14.50% <50.00%> (+0.55%) ⬆️

... and 783 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@router-tests/protocol/router_plugin_test.go`:
- Around line 624-956: Enable telemetry for at least one subtest so the
telemetry-injection regression path is exercised: pick a subtest (e.g., the
"unsafe headers are absent from metadata" case) and modify the testenv.Config
passed to testenv.Run to turn telemetry on (for example by adding Telemetry:
testenv.TelemetryConfig{Enabled: true} or the equivalent flag in your test
harness), keeping the rest of the RouterOptions (captureInterceptor,
core.WithHeaderRules) unchanged so captureInterceptor, testenv.Run and
testenv.Config still validate that telemetry-injected outgoing metadata does not
overwrite/escape header propagation rules.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d7778b56-1b63-420e-bbd2-035501e41492

📥 Commits

Reviewing files that changed from the base of the PR and between 8acd38f and a5765a1.

📒 Files selected for processing (8)
  • router-tests/protocol/router_plugin_test.go
  • router-tests/router_oci_plugin_test.go
  • router/core/graph_server.go
  • router/core/router.go
  • router/core/router_config.go
  • router/pkg/grpcconnector/grpccommon/grpc_plugin_client.go
  • router/pkg/grpcconnector/grpcplugin/grpc_plugin.go
  • router/pkg/grpcconnector/grpcpluginoci/grpc_oci_plugin.go

Comment thread router-tests/protocol/router_plugin_test.go
Copy link
Copy Markdown
Contributor

@SkArchon SkArchon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one comment

Comment thread router-tests/protocol/router_plugin_test.go
@asoorm asoorm requested a review from a team as a code owner May 26, 2026 08:52
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
router-tests/protocol/router_plugin_test.go (1)

622-628: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Enable telemetry for this header-forwarding suite invocation.

This run still executes the matrix without telemetry, so the metadata-merge regression path is not exercised.

Proposed minimal patch
 func TestRouterPluginWithHeaderForwarding(t *testing.T) {
 	t.Run("Should send http headers as gRPC metadata to subgraphs", func(t *testing.T) {
 		t.Parallel()
 
+		exporter := tracetest.NewInMemoryExporter(t)
 		testenv.RunGRPCPluginHeaderCases(t, testenv.Config{
+			TraceExporter:            exporter,
 			RouterConfigJSONTemplate: testenv.ConfigWithPluginsJSONTemplate,
 			Plugins: testenv.PluginConfig{
 				Enabled: true,
 				Path:    "../../router/plugins",
 			},
 		})
 	})
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@router-tests/protocol/router_plugin_test.go` around lines 622 - 628, The
header-forwarding test call currently omits telemetry and must enable it so the
metadata-merge regression path is exercised: in the
testenv.RunGRPCPluginHeaderCases invocation, add a telemetry flag to the
testenv.Config literal (e.g. TelemetryEnabled: true) alongside
RouterConfigJSONTemplate and Plugins so the matrix runs with telemetry enabled;
update the test invocation that uses testenv.Config to include this new field
(referencing RunGRPCPluginHeaderCases and testenv.Config/Plugins).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@router-tests/protocol/router_plugin_test.go`:
- Around line 622-628: The header-forwarding test call currently omits telemetry
and must enable it so the metadata-merge regression path is exercised: in the
testenv.RunGRPCPluginHeaderCases invocation, add a telemetry flag to the
testenv.Config literal (e.g. TelemetryEnabled: true) alongside
RouterConfigJSONTemplate and Plugins so the matrix runs with telemetry enabled;
update the test invocation that uses testenv.Config to include this new field
(referencing RunGRPCPluginHeaderCases and testenv.Config/Plugins).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cb765fbc-f3a9-4c89-a02d-0df72f12d396

📥 Commits

Reviewing files that changed from the base of the PR and between a5765a1 and b8e02d8.

📒 Files selected for processing (3)
  • router-tests/protocol/router_plugin_test.go
  • router-tests/router_oci_plugin_test.go
  • router-tests/testenv/grpc_plugin_header_cases.go

Comment thread router-tests/testenv/grpc_plugin_header_cases.go
Comment thread router-tests/testenv/grpc_plugin_header_cases.go
Comment thread router-tests/testenv/grpc_plugin_header_cases.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants